import React, { memo, useState, useEffect } from 'react';
import QRCode from 'qrcode.react';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import Draggable from 'react-draggable';
import type { Layout } from 'react-grid-layout';
import GridLayout from 'react-grid-layout';
import { Rnd } from 'react-rnd';
import {
  useContextMenu,
  Menu,
  Item,
  Separator,
  ItemParams,
} from 'react-contexify';
import { dynamic } from 'umi';
import { Spin, Radio } from 'antd';

const AsyncImportComponent = dynamic({
  loader: async function () {
    const { default: UserInfo } = await import(
      /* webpackChunkName: "ComponentUserInfo" */ '@/components/UserInfo'
    );
    return () => <UserInfo />;
  },
  loading: () => (
    <div style={{ paddingTop: 10, textAlign: 'center' }}>
      <Spin />
    </div>
  ),
});

const Box = () => {
  const [{ canDrop, isOver }, drop] = useDrop(() => ({
    accept: 'target',
    drop: () => ({ name: '黑色盒子' }),
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  }));
  const isActive = canDrop && isOver;
  return (
    <div
      ref={drop}
      style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        width: 300,
        height: 300,
        backgroundColor: '#333',
        color: '#FFF',
      }}
    >
      {isActive ? '释放拖拽目标' : '拖拽目标来这里'}
    </div>
  );
};
const Target = (props: { name: string }) => {
  const { name } = props;
  const [{ isDragging }, drag] = useDrag(() => ({
    item: () => ({ name }),
    type: 'target',
    end: (item, monitor) => {
      const dropResult = monitor.getDropResult() as { name: string };
      if (item && dropResult) {
        console.log(item);
        console.log(dropResult);
        alert(`你拖拽了 ${item.name} 进入 ${dropResult.name}!`);
      }
    },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
      handlerId: monitor.getHandlerId(),
    }),
  }));
  const opacity = isDragging ? 0.4 : 1;
  return (
    <div
      ref={drag}
      style={{
        margin: '10px',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        width: 50,
        height: 50,
        color: 'white',
        border: '1px dashed gray',
        cursor: 'move',
        opacity,
      }}
    >
      {name}
    </div>
  );
};

const ReactDndExample = memo(() => (
  <div>
    <div style={{ overflow: 'hidden', clear: 'both' }}>
      <Box />
    </div>
    <div style={{ overflow: 'hidden', clear: 'both' }}>
      <Target name="目标" />
    </div>
  </div>
));

const LayoutBasicDemo = memo(() => {
  const layout = [
    { i: 'a', x: 0, y: 4, w: 24, h: 48, isBounded: true },
    { i: 'b', x: 0, y: 57, w: 24, h: 57, isBounded: true },
  ];
  const layoutChange = (layout: Layout) => {
    console.log(layout);
  };
  return (
    <div style={{ width: 512, height: 768 }} className="bd1">
      <GridLayout
        width={512}
        margin={[0, 0]}
        cols={24}
        rowHeight={1}
        onLayoutChange={layoutChange}
      >
        {layout.map((item) => (
          <div
            key={item.i}
            data-grid={item}
            style={{ backgroundColor: 'blue' }}
          >
            {item.i}
          </div>
        ))}
      </GridLayout>
    </div>
  );
});

const ReactRndDemo = memo(() => {
  const [state, setState] = useState({
    w: 200,
    h: 200,
    x: 0,
    y: 0,
  });
  const dragStop = (e, d) => {
    setState((state) => ({ ...state, x: d.x, y: d.y }));
  };
  const resize = (e, direction, ref, delta, position) => {
    setState({
      w: ref.offsetWidth,
      h: ref.offsetHeight,
      ...position,
    });
  };
  useEffect(() => {
    const { w, h, x, y } = state;
    console.log(`w: ${w},h: ${h},x: ${x},y: ${y}`);
  }, [state]);
  return (
    <div
      style={{
        position: 'relative',
        width: 500,
        height: 500,
        backgroundColor: 'pink',
      }}
    >
      <Rnd
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          border: 'solid 1px #ddd',
          background: '#f0f0f0',
        }}
        size={{
          width: state.w,
          height: state.h,
        }}
        position={{
          x: state.x,
          y: state.y,
        }}
        onDragStop={dragStop}
        onResize={resize}
        bounds="parent"
      >
        001
      </Rnd>
    </div>
  );
});

interface ItemProps {
  id: number;
}

// Defined just for documentation purpose
type ItemData = any;
const items = [{ id: 111 }, { id: 222 }];
const ReactContexifyDemo = memo(() => {
  const MENU_ID = 'menu';
  const { show } = useContextMenu({
    id: MENU_ID,
  });
  function displayMenu(e: React.MouseEvent) {
    // pass the item id so the `onClick` on the `Item` has access to it
    console.log(e.currentTarget.getAttribute('data-action'));
    show(e, { props: { id: Number(e.currentTarget.id) } });
  }

  function handleItemClick({
    event,
    props,
    data,
    triggerEvent,
  }: ItemParams<ItemProps, ItemData>) {
    switch (event.currentTarget.id) {
      case 'remove':
        // logic to remove the row
        console.log(props.id); // contain to item.id passed by `show`
        break;
      case 'share':
        // logic to share
        break;
      case 'email':
        //logic to send email
        break;
      case 'sponsor':
        //logic to open sponsor page
        break;
    }
  }
  return (
    <div
      style={{
        position: 'relative',
        width: 500,
        height: 500,
        backgroundColor: 'pink',
        color: 'black',
      }}
    >
      <ul>
        {items.map((item) => (
          <li
            className="p20"
            data-action={`action-${item.id}`}
            id={`${item.id}`}
            key={item.id}
            onContextMenu={displayMenu}
          >
            {/* render content of my list item */}
            {item.id}
          </li>
        ))}
      </ul>
      <Menu id={MENU_ID}>
        <Item id="remove" onClick={handleItemClick}>
          Remove row
        </Item>
        <Separator />
        <Item id="share" onClick={handleItemClick}>
          Share
        </Item>
        <Item id="email" onClick={handleItemClick}>
          Send email
        </Item>
        <Item id="sponsor" onClick={handleItemClick}>
          Sponsor my work
        </Item>
      </Menu>
    </div>
  );
});

export default function Help() {
  return (
    <div className="h100p overflow-y-auto">
      <h1>帮助页</h1>
      <hr />
      <Radio.Group>
        <Radio value={1}>A</Radio>
        <Radio value={2}>B</Radio>
        <Radio value={3}>C</Radio>
        <Radio value={4}>D</Radio>
      </Radio.Group>
      <h2>☞ React-contexify</h2>
      <ReactContexifyDemo />
      <h2>☞ QRcode</h2>
      <QRCode value="https://www.baidu.com/" />
      <h2>☞ React-Dnd Example</h2>
      <DndProvider backend={HTML5Backend}>
        <ReactDndExample />
      </DndProvider>
      <h2>☞ React-Draggable Example</h2>
      <Draggable
        axis="y"
        handle=".handle"
        defaultPosition={{ x: 0, y: 0 }}
        position={undefined}
        grid={[25, 25]}
        scale={1}
        // onStart={this.handleStart}
        // onDrag={this.handleDrag}
        // onStop={this.handleStop}
      >
        <div className="handle pointer">点这里操作拖拽</div>
      </Draggable>
      <h2>☞ 动态加载组件</h2>
      <AsyncImportComponent />
      <h2>☞ react-grid-layout 响应式栅格布局系统</h2>
      <LayoutBasicDemo />
      <h2>☞ React-rnd</h2>
      <ReactRndDemo />
    </div>
  );
}
